from constants import *
import os
from means import *
import cls
import file

__weight_cls = "YLBodyWeightLevelTool"
__get_stage_weight_level_method = "getStageWeightLevel"
__weight_param = "weight"
__levels_param = "levels"
__month_param = "month"
__gender_param = "gender"

__get_male_weight_level_method = "getMaleWeightLevel"
__get_female_weight_level_method = "getFemaleWeightLevel"

__get_weight_level_method = "getWeightLevel"

def __generateGetWeightLevelMethod(dev_language):
    parmas_list = ""
    body = ""
    result = WeightLevel.enum
    weight_enum = WeightLevel(dev_language)
    levels = [(weight_enum.getLean(), "%s[0]"%__levels_param), (weight_enum.getThin(), "%s[1]"%__levels_param), (weight_enum.getStand(), "%s[2]"%__levels_param), (weight_enum.getFatty(), "%s[3]"%__levels_param)]

    if dev_language == DevLanguage.objc:
        parmas_list = [Params(__levels_param, "NSArray *"), Params(__weight_param, "double")]
        for item in levels:
            body += "if (%s < [%s floatValue]) return %s;\n"%(__weight_param, item[1], item[0])
        body += "return %s;\n"%weight_enum.getOver()
    else:
        parmas_list = [Params(__levels_param, "Array<Double>"), Params(__weight_param, "Double")]
        for item in levels:
            body += "if (%s < %s) return %s;\n"%(__weight_param, item[1], item[0])
        body += "return %s;\n"%weight_enum.getOver()
    return generateMethod(dev_language, __get_stage_weight_level_method, parmas_list, body, result)

def __generateGenderWeightLevelMethod(dev_language, method, list_tuple):
    parmas_list = ""
    body = ""
    result = WeightLevel.enum
    weight_enum = WeightLevel(dev_language)
    if dev_language == DevLanguage.objc:
        parmas_list = [Params(__month_param, "int"), Params(__weight_param, "double")]
        for item in list_tuple:
            objc_list = ""
            for level in item[1]:
                objc_list += '@(%s), '%level
            objc_list = '@[%s]'%(objc_list[:-2])
            body += "if(%s <= %s) return [self %sWith%s:%s %s:%s];\n"%(__month_param, item[0], __get_stage_weight_level_method, __levels_param.capitalize(), objc_list, __weight_param, __weight_param)
        body += "return %s\n"%weight_enum.getNone()
    else:
        parmas_list = [Params(__month_param, "int"), Params(__weight_param, "double")]
        for item in list_tuple:
            objc_list = ""
            for level in item[1]:
                objc_list += '%s, '%level
            objc_list = 'arrayof(%s)]'%(objc_list[:-2])
            body += "if(%s <= %s) return %s(%s: %s, %s: %s);\n"%(__month_param, item[0], __get_stage_weight_level_method, __levels_param, objc_list, __weight_param, __weight_param)
        body += "return %s\n"%weight_enum.getNone()
    return generateMethod(dev_language, method, parmas_list, body, result)

def __generateImplWeightLevelMethod(dev_language):
    parmas_list = ""
    body = ""
    result = WeightLevel.enum
    weight_enum = WeightLevel(dev_language)
    if dev_language == DevLanguage.objc:
        parmas_list = [Params(__month_param, "int"), Params(__weight_param, "double"), Params(__gender_param, Gender.enum)]
        body = "if (%s == %s) return [self %sWith%s:%s %s:%s];\nreturn [self %sWith%s:%s %s:%s];\n"%(__gender_param, Gender.male, __get_male_weight_level_method, __month_param.capitalize(), __month_param, __weight_param, __weight_param, __get_female_weight_level_method, __month_param.capitalize(), __month_param, __weight_param, __weight_param)
    else:
        parmas_list = [Params(__month_param, "Int"), Params(__weight_param, "Double"), Params(__gender_param, "Int")]
        body = "if (%s == 1) return %s(%s: %s, %s: %s);\nreturn %s(%s: %s, %s: %s);\n"%(__gender_param, __get_male_weight_level_method, __month_param, __month_param, __weight_param, __weight_param, __get_female_weight_level_method, __month_param, __month_param, __weight_param, __weight_param)
    return generateMethod(dev_language, __get_weight_level_method, parmas_list, body, result,  None if dev_language == DevLanguage.objc else "男 1 女 0")


def __generateInterWeightLevelObjcMethod():
    return "+ (%s)%sWith%s:(int)%s %s:(%s)%s %s:(double)%s;"%(WeightLevel.enum, __get_weight_level_method, __month_param.capitalize(), __month_param, __gender_param, Gender.enum, __gender_param, __weight_param, __weight_param)

def __generateWeightLevelEnum(dev_language):
    if dev_language == DevLanguage.objc:
        weight_enum = WeightLevel(DevLanguage.objc)
        return "typedef enum{\n%s = 0,\n%s = 1,\n%s = 2,\n%s = 3,\n%s = 4,\n%s = 5,\n}%s;"%(weight_enum.getNone(), weight_enum.getStand(), weight_enum.getFatty(), weight_enum.getThin(), weight_enum.getOver(),weight_enum.getLean(),WeightLevel.enum)
    
    return "enum class %s {\n%s,\n%s,\n%s,\n%s,\n%s,\n%s\n}"%(WeightLevel.enum, WeightLevel.none, WeightLevel.stand, WeightLevel.fatty, WeightLevel.thin, WeightLevel.over, WeightLevel.lean)

def generateFile(dev_language, male_list_tuple, female_list_tuple):
    method_1 = __generateImplWeightLevelMethod(dev_language)
    method_2 = __generateGenderWeightLevelMethod(dev_language, __get_male_weight_level_method, male_list_tuple)
    method_3 = __generateGenderWeightLevelMethod(dev_language, __get_female_weight_level_method, female_list_tuple)
    method_4 = __generateGetWeightLevelMethod(dev_language)

    method_impl = method_1 + "\n" + method_2 + "\n" + method_3 + "\n" + method_4

    enum_str = __generateWeightLevelEnum(dev_language)

    if dev_language == DevLanguage.kotlin:
        cls_str = cls.generateKotlin(__weight_cls, method_impl, enum_str)
        kt_path = file.getKtRootPath()
        cls_path = os.path.join(kt_path, __weight_cls + '.kt')
        with open(cls_path, 'w+') as fs:
            fs.write(cls_str)
    else:
        method_inter = __generateInterWeightLevelObjcMethod()
        cls_impl = cls.generateObjcImpl(__weight_cls, method_impl)
        cls_inter = cls.generateObjcInter(__weight_cls, method_inter, enum_str)
        objc_path = file.getObjcRootPath()
        h_path = os.path.join(objc_path, __weight_cls + ".h")
        m_path = os.path.join(objc_path, __weight_cls + ".m")
        with open(m_path, 'w+') as fs:
            fs.write(cls_impl)

        with open(h_path, 'w+') as fs:
            fs.write(cls_inter)

def generateWeightLevelCls(ws):
    male_levels = []
    female_levels = []
    for row in ws.iter_rows(min_row = 3):
        male_month = row[1].value
        female_month = row[14].value
        if male_month == None:
            male_month = row[0].value
            male_month = int(float(male_month[:-1]) * 12)
        if female_month == None:
            female_month = row[13].value
            female_month = int(float(female_month[:-1]) * 12)

        if row[3].value != None and row[4].value != None and row[6].value != None and row[7].value != None:
            male_level = (male_month,[row[3].value, row[4].value, row[6].value, row[7].value])
            male_levels.append(male_level)

        if row[16].value != None and row[17].value != None and row[19].value != None and row[20].value != None:
            female_level = (female_month,[row[16].value, row[17].value, row[19].value, row[20].value])
            female_levels.append(female_level)
    
    generateFile(DevLanguage.kotlin, male_levels, female_levels)
    generateFile(DevLanguage.objc, male_levels, female_levels)



